package city.spring.modules.oldman.service.impl;

import city.spring.modules.cardinfo.entity.CardNumberEntity;
import city.spring.modules.cardinfo.service.CardNumberService;
import city.spring.modules.expense.entity.ExpenseRecordEntity;
import city.spring.modules.expense.repository.ExpenseRecordRepository;
import city.spring.modules.expense.service.ExpenseRecordService;
import city.spring.modules.oldman.entity.ServiceReservationRecordEntity;
import city.spring.modules.oldman.repository.ServiceReservationRecordRepository;
import city.spring.modules.oldman.service.ServiceReservationRecordService;
import city.spring.modules.oldman.vo.ServiceReservationRecordEntityVO;
import city.spring.modules.system.entity.UserEntity;
import city.spring.modules.system.service.UserService;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.NonNull;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Service：
 * 服务预定记录
 *
 * @author pxm
 * @date 2020-08-19 15:52:29
 */
@CacheConfig(cacheNames = {ServiceReservationRecordServiceImpl.CACHE_NAME})
@Transactional(rollbackFor = Exception.class)
@Service
public class ServiceReservationRecordServiceImpl extends ServiceImpl<ServiceReservationRecordRepository, ServiceReservationRecordEntity> implements ServiceReservationRecordService {

    private final ServiceReservationRecordRepository serviceReservationRecordRepository;
    private final UserService userService;
    private final CardNumberService cardNumberService;
    private final ExpenseRecordService expenseRecordService;
    private final ExpenseRecordRepository expenseRecordRepository;

    public ServiceReservationRecordServiceImpl(ServiceReservationRecordRepository serviceReservationRecordRepository, UserService userService, CardNumberService cardNumberService, ExpenseRecordService expenseRecordService, ExpenseRecordRepository expenseRecordRepository) {
        this.serviceReservationRecordRepository = serviceReservationRecordRepository;
        this.userService = userService;
        this.cardNumberService = cardNumberService;
        this.expenseRecordService = expenseRecordService;
        this.expenseRecordRepository = expenseRecordRepository;
    }

    @Override
    public void saveServiceReservationRecord(ServiceReservationRecordEntity entity, @NonNull Principal user) {
        // 登记人
        UserEntity userEntity = userService.getUserByIdOrAccount(user.getName());
        entity.setRegistrant(userEntity.getId());
        //订单编号： 获取当前时间，格式化为yyyyMMddmmss，转为string类型，拼接INFO+yyyyMMddmmss作为编号
        String nowTimestr = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String numcode = "FW" + nowTimestr;
        entity.setOrderNum(numcode);

        // 更新预存款余额
        CardNumberEntity cardNumberEntity = cardNumberService.getByPersonId(entity.getOldmanId());
        cardNumberEntity.setDepositBalance(cardNumberEntity.getDepositBalance().subtract(entity.getReceiveFee()));
        cardNumberService.updateCardNumber(cardNumberEntity);

        // 支付，生成费用记录
        ExpenseRecordEntity expenseRecordEntity = new ExpenseRecordEntity();
        expenseRecordEntity.setOldmanId(entity.getOldmanId());
        expenseRecordEntity.setBedNum(entity.getBedNumber());
        expenseRecordEntity.setMoney(entity.getReceiveFee());
        expenseRecordEntity.setType("消费");
        expenseRecordEntity.setCategory("服务预定");
        expenseRecordEntity.setRegistrant(entity.getRegistrant());
        expenseRecordEntity.setRemarks("服务预定自动扣款");
        expenseRecordEntity.setBillId(numcode);
        expenseRecordEntity.setHappenTime(new Date());
        expenseRecordService.save(expenseRecordEntity);

        if (!save(entity)) {
            throw new RuntimeException("保存信息失败");
        }
    }

    @Override
    public void updateServiceReservationRecord(ServiceReservationRecordEntity entity) {
        // 使用 updateById(entity); 修改数据时，将会修改 entity 对象中所有非null数据，如果某个字段为null，将会忽略该字段的修改
        if (!updateById(entity)) {
            throw new RuntimeException("修改信息失败");
        }
    }

    @Override
    public void deleteServiceReservationRecord(String primaryKey) {
        removeById(primaryKey);
    }

    @Override
    public void deleteServiceReservationRecord(List<String> primaryKeys) {
        removeByIds(primaryKeys);
    }

    /**
     * 分页获取的服务预定记录
     *
     * @param page    分页对象
     * @param wrapper 查询对象
     * @return 服务预定记录
     */
    @Override
    public IPage<ServiceReservationRecordEntityVO> listPage(Page<? extends ServiceReservationRecordEntity> page, Wrapper<? extends ServiceReservationRecordEntity> wrapper) {
        return baseMapper.listPage(page, wrapper);
    }

    @Override
    public void orderStatusChange(String id, ServiceReservationRecordEntity entity) {
        // 0:未执行 1：已执行
        entity.setOrderStatus(1);
        baseMapper.orderStatusChange(id, entity);
    }

    @Override
    public void orderCancel(String id, @NonNull Principal user) {
        // 登记人
        UserEntity userEntity = userService.getUserByIdOrAccount(user.getName());

        // 1、订单执行和支付状态改为“已取消” 2
        ServiceReservationRecordEntity serviceReservationRecordEntity = getById(id);
        serviceReservationRecordEntity.setOrderStatus(2);
        serviceReservationRecordEntity.setPayStatus(2);
        updateServiceReservationRecord(serviceReservationRecordEntity);
        // 2、退款：预存款余额=原预存款余额+订单的应收费用
        CardNumberEntity cardNumberEntity = cardNumberService.getByPersonId(serviceReservationRecordEntity.getOldmanId());
        cardNumberEntity.setDepositBalance(cardNumberEntity.getDepositBalance().add(serviceReservationRecordEntity.getReceiveFee()));
        cardNumberService.updateCardNumber(cardNumberEntity);
        // 3、作废原先的费用记录，状态：作废，作废时间
        ExpenseRecordEntity invalidEntity = expenseRecordRepository.getByBillId(serviceReservationRecordEntity.getOrderNum());
        invalidEntity.setIsInvalid(1);
        invalidEntity.setInvalidTime(new Date());
        expenseRecordService.updateExpenseRecord(invalidEntity);

        // 4、新增费用记录，即退款记录
        ExpenseRecordEntity expenseRecordEntity = new ExpenseRecordEntity();
        expenseRecordEntity.setOldmanId(serviceReservationRecordEntity.getOldmanId());
        expenseRecordEntity.setBedNum(serviceReservationRecordEntity.getBedNumber());
        expenseRecordEntity.setMoney(serviceReservationRecordEntity.getReceiveFee());
        expenseRecordEntity.setType("退款");
        expenseRecordEntity.setCategory("服务预定");
        expenseRecordEntity.setRemarks("服务预定-订单取消及退款");
        expenseRecordEntity.setRegistrant(userEntity.getId());
        expenseRecordEntity.setBillId(serviceReservationRecordEntity.getOrderNum());
        expenseRecordEntity.setHappenTime(new Date());
        expenseRecordService.save(expenseRecordEntity);
    }

    @Override
    public Object[] getUnExecutedProject(String oldmanId) {
        List<ServiceReservationRecordEntityVO> sEntityVO = serviceReservationRecordRepository.getUnExecutedProject(oldmanId);
        Object[] objs = new Object[1];
        if (sEntityVO == null) {
            // 0: 没有未执行的订单 1：有未执行的订单
            objs[0] = 0;
        } else {
            objs[0] = 1;
        }
        return objs;
    }
}